package org.rcgwt.client.ui.validator.messages;

import java.util.ArrayList;
import java.util.List;

import org.rcgwt.client.ui.fields.ValidatedTextField;
import org.rcgwt.client.ui.validator.events.MessageEvent;

import com.google.gwt.user.client.ui.Widget;

public class MessageManager implements IMessageManager {

	private static final MessageManager INSTANCE = new MessageManager();
	private List<Widget> widgets;
	private List<MessageEvent> events;
	private List<IMessageDisplay> displays;
	private IValidationContext context;

	private MessageManager() {
		widgets = new ArrayList<Widget>();
		displays = new ArrayList<IMessageDisplay>();
		events = new ArrayList<MessageEvent>();
	}

	public static MessageManager create() {
		return INSTANCE;
	}

	@Override
	public void addField(Widget f) {
		widgets.add(f);
		if (f instanceof ValidatedTextField) {
			((ValidatedTextField) f).setManager(this);
			((ValidatedTextField) f).setValidAfterSubmit(true);
		}
	}

	@Override
	public void addMessageEvent(MessageEvent me) {
		events.add(me);
	}

	@Override
	public void addMessageDisplay(IMessageDisplay md, Widget w) {
		displays.add(md);
		md.setFor(w);
	}

	@Override
	public void addGlobalMessageDisplay(IMessageDisplay md) {
		displays.add(md);
		md.setGlobalOnly(true);
	}

	@Override
	public void valid() {
		clearMessages();
		for (int i = 0; i < widgets.size(); i++) {
			if (widgets.get(i) instanceof ValidatedTextField) {
				((ValidatedTextField) widgets.get(i)).valid(context);
			}
		}
		dispatchMessages();
	}

	public List<Widget> getWidgets() {
		return widgets;
	}

	public void setWidgets(List<Widget> widgets) {
		this.widgets = widgets;
	}

	public List<MessageEvent> getEvents() {
		return events;
	}

	public void setEvents(List<MessageEvent> e) {
		this.events = e;
	}

	public List<IMessageDisplay> getDisplays() {
		return displays;
	}

	public void setDisplays(List<IMessageDisplay> displays) {
		this.displays = displays;
	}

	public void setContext(IValidationContext context) {
		this.context = context;
	}

	public IValidationContext getContext() {
		return context;
	}

	@Override
	public void dispatchMessages() {
		for (MessageEvent event : events) {
			Widget w = event.getSender();
			/* Global only displays */
			if (w == null) {
				for (IMessageDisplay display : displays) {
					if (display.isGlobalOnly() == true) {
						display.setMessage(event.getMessage());
					}
				}
			}
			/* Specific messages displays */
			for (IMessageDisplay display : displays) {
				Widget wfor = display.getFor();
				if (w == wfor) {
					display.setMessage(event.getMessage());
				}
			}
		}
		events.clear();
	}

	public void clearMessages() {
		for (IMessageDisplay display : displays) {
			display.clearMessage();
		}
	}

	@Override
	public String toString() {
		return "MessageManager [displays=" + displays + ", events=" + events
				+ ", widgets=" + widgets + "]";
	}
}
